package com.ok.common.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.viewbinding.ViewBinding
import com.gyf.immersionbar.ktx.immersionBar
import com.kongzue.dialogx.dialogs.WaitDialog
import com.ok.common.R
import com.ok.common.common.Constants.MIN_CLICK_DELAY_TIME
import com.ok.common.manager.ActivityManager
import com.ok.common.utils.EventUtils
import me.jessyan.autosize.internal.CustomAdapt
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.lang.reflect.ParameterizedType

/**
 * Activity基类
 */
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity(), CustomAdapt, View.OnClickListener {

    protected lateinit var mBinding: VB

    private var lastButtonId = -1

    private var lastClickTime = 0L

    @LayoutRes
    protected open val layoutId = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ActivityManager.getInstance().addActivity(this)
        if (isRegisterEvent) {
            EventUtils.register(this)
        }
        initViewDataBinding()
        initView(savedInstanceState)
        initImmersionBar()
        initObserve()
        initData()
        initListener()
    }

    abstract fun initView(savedInstanceState: Bundle?)

    open fun initImmersionBar() {
        immersionBar()
    }

    open fun initObserve() {}

    open fun initData() {}

    open fun initListener() {}

    override fun isBaseOnWidth(): Boolean = true

    override fun getSizeInDp(): Float = 0F

    //防止多次点击的点击事件
    open fun mClick(v: View?) {}

    open fun handleEvent(event: BaseEvent) {}

    open fun handleStickyEvent(event: BaseEvent) {}

    open var isRegisterEvent = false

    @Subscribe(threadMode = ThreadMode.MAIN)
    open fun onEventBusCome(event: BaseEvent?) {
        if (event != null) {
            handleEvent(event)
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
    open fun onStickyEventBusCome(event: BaseEvent?) {
        if (event != null) {
            handleStickyEvent(event)
        }
    }

    override fun onClick(v: View?) {
        var currentButtonId = v?.id
        if (!fastClick() && (lastButtonId == currentButtonId)) {
            return
        }
        if (currentButtonId != null) {
            lastButtonId = currentButtonId
        }
        mClick(v)
    }

    private fun fastClick(): Boolean {
        if (System.currentTimeMillis() - lastClickTime <= MIN_CLICK_DELAY_TIME) {
            return false
        }
        lastClickTime = System.currentTimeMillis()
        return true
    }

    /**
     * DataBinding or ViewBinding
     */
    private fun initViewDataBinding() {
        val type = javaClass.genericSuperclass
        if (type is ParameterizedType) {
            val cls = type.actualTypeArguments.map { it as Class<*> }
                .first { ViewBinding::class.java.isAssignableFrom(it) }
            when {
                ViewDataBinding::class.java.isAssignableFrom(cls) && cls != ViewDataBinding::class.java -> {
                    if (layoutId == 0) throw IllegalArgumentException("Using DataBinding requires overriding method layoutId")
                    mBinding = DataBindingUtil.setContentView(this, layoutId)
                    (mBinding as ViewDataBinding).lifecycleOwner = this
                }

                ViewBinding::class.java.isAssignableFrom(cls) && cls != ViewBinding::class.java -> {
                    cls.getDeclaredMethod("inflate", LayoutInflater::class.java).let {
                        @Suppress("UNCHECKED_CAST") mBinding = it.invoke(null, layoutInflater) as VB
                        setContentView(mBinding.root)
                    }
                }

                else -> {
                    if (layoutId == 0) throw IllegalArgumentException("If you don't use ViewBinding, you need to override method layoutId")
                    setContentView(layoutId)
                }
            }
        } else throw IllegalArgumentException("Generic error")
    }

    override fun finish() {
        super.finish()
        this.overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right)
    }

    open fun showLoading(text: String = getString(R.string.loading)) {
        WaitDialog.show(text)
    }

    open fun dismissLoading() {
        WaitDialog.dismiss()
    }

    override fun onDestroy() {
        super.onDestroy()
        if (isRegisterEvent) {
            EventUtils.unregister(this)
        }
        ActivityManager.getInstance().removeActivity(this)
    }

}